using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Reflection;
using System.Linq;

public class ObjectSerializer<T>
{
    protected IFormatter iformatter;
    public ObjectSerializer()
    {
        this.iformatter = new BinaryFormatter();
    }
    public T GetSerializedObject(string filename)
    {
        if (File.Exists(filename))
        {
            Stream inStream = new FileStream(
                filename,
                FileMode.Open,
                FileAccess.Read,
                FileShare.Read);
            T obj = (T)this.iformatter.Deserialize(inStream);
            inStream.Close();
            return obj;
        }
        return default(T);
    }
    public List<T> GetSerializedCollection(string filename)
    {
		List<T> ret = new List<T>();
		
        if (File.Exists(filename))
        {
            Stream inStream = new FileStream(
                filename,
                FileMode.Open,
                FileAccess.Read,
                FileShare.Read);
			T obj;
			while((obj = (T)this.iformatter.Deserialize(inStream)) !=null){
				ret.Add(obj);
			}
            inStream.Close();
            return ret;
        }
        return ret;
    }
	public void SaveSerializedCollection(List<T> objs, string filename)
	{
		 Stream outStream = new FileStream(
            filename,
            FileMode.Create,
            FileAccess.Write,
            FileShare.None);
		foreach(T obj in objs)
	        this.iformatter.Serialize(outStream, obj);
        outStream.Close();
	}
    public void SaveSerializedObject(T obj, string filename)
    {
        Stream outStream = new FileStream(
            filename,
            FileMode.Create,
            FileAccess.Write,
            FileShare.None);
        this.iformatter.Serialize(outStream, obj);
        outStream.Close();
    }
}

public class IOHelper{
	public static long ReadLong(Stream sm)
	{
		Byte[] bf = new Byte[4];
		sm.Read(bf,0,4);
		return 	(long) BitConverter.ToInt32(bf,0);
	}
	
	public static int ReadInt(Stream sm)
	{
		Byte[] bf = new Byte[4];
		sm.Read(bf,0,4);
		return 	(int) BitConverter.ToInt32(bf,0);
	}
}

public class IOClass
{
	public static List<Type> GetAllDerived(Type baseClass)
	{
		Type baseType = baseClass;
		var descendantTypes =
	    	from type in baseType.Assembly.GetTypes()
	    	where !type.IsAbstract
	       	&& type.IsSubclassOf(baseType)
		    select type;
		return descendantTypes.ToList();
	}
	
	public static string[] GetAllDerivedST(Type baseClass)
	{
		List<Type> list = GetAllDerived(baseClass);
		string[] ret = new string[list.Count()];
		int p=0;
		foreach(Type t in list)
		{
			ret[p]=t.ToString();
			p++;
		}
		return ret;
	}
			
}